package Fp

import (
	"fmt"
	"db2s/parDef"
	"strings"
	"sync/atomic"
)

func (sp TaskDistribution) subGetLeftDirection() []map[string]string {
	return getLeftDirection(sp.Second.Batch.WhereGenerate.RightDirection)
}
func (sp TaskDistribution) subGetRightDirection() []map[string]string {
	return getRightDirection(sp.Second.Batch.WhereGenerate.RightDirection)
}
func (sp TaskDistribution) subSendMsg(s parDef.IndexPart) {
	sp.Second.Result <- s
}
func (sp TaskDistribution) subCloseMsg() {
	close(sp.Second.Result)
}
func (sp TaskDistribution) subGetWcValue() []string {
	return getWcValue(sp.Second.WC)
}
func (sp TaskDistribution) subGetWsValue() []string {
	return getWcValue(sp.Second.WS)
}
func (sp TaskDistribution) subGetSwsMd5() string {
	return fmt.Sprintf("%v", getAtomicValue(sp.Second.SwsMd5))
}
func (sp TaskDistribution) subErrClose(logSeq1, logSeq2 int64) bool {
	var (
		event = "[subErrClose]"
	)
	if sp.ErrEnd != nil {
		if val := atomic.LoadInt64(sp.ErrEnd); val < 0 {
			errorActive(fmt.Sprintf("(%d-%v) %v setupEnd&: setupEnd&: Received an error of table %v.%v(%v).", logSeq1, logSeq2, event, sp.TableObject.Schema, sp.TableObject.Table, sp.TableObject.PartitionName))
			sp.subSendMsg(parDef.IndexPart{Error: fmt.Sprintf("%v", getAtomicValue(sp.Second.ErrorStr))})
			return true
		}
	}
	return false
}
func (sp TaskDistribution) subQueryConditionsLeftIndentation() {
	var newLeftDirection, newRightDirection []map[string]string
	for k, v := range sp.subGetLeftDirection()[:len(sp.subGetLeftDirection())-1] {
		if k == len(sp.subGetLeftDirection())-2 && (strings.EqualFold(v["querySymbolLeft"], ">=") || strings.EqualFold(v["querySymbolLeft"], "=")) {
			v["querySymbolLeft"] = ">"
			newLeftDirection = append(newLeftDirection, v)
			break
		} else {
			newLeftDirection = append(newLeftDirection, v)
			newRightDirection = append(newRightDirection, sp.subGetLeftDirection()[k])
		}
	}
	swapAtomicValue(sp.Second.Batch.WhereGenerate.LeftDirection, newLeftDirection)
	swapAtomicValue(sp.Second.Batch.WhereGenerate.RightDirection, newRightDirection)
	swapAtomicValue(sp.Second.WS, []string{})
	swapAtomicValue(sp.Second.WC, []string{})
	//infoActive(fmt.Sprintf(fmt.Sprintf("(%d-%v) %v setup5&: index chunk segment [not value] result of table:%v.%v(%v) index Column:%v index Column dataType:%v. [ls=0] ls:%v,first contitions:ws:%v wc %v sws: left %v right %v", logSeq, sps.getFirstSemLogSeq(), event, sps.TableObject.Schema, sps.TableObject.Table, sps.TableObject.PartitionName, cn1, cds, s.Limit.Pagination, ws, wc, s.WhereGenerate.LeftDirection, s.WhereGenerate.RightDirection)))
}
func (sp TaskDistribution) boundaryIf(s parDef.IndexPart) (res bool, err error) {
	var (
		segmentCompareValue []int
	)
	if segmentCompareValue, err = newColumnValue(sp.Full, getTypeValue(sp.Second.Name), getTypeValue(sp.Second.Type), getWsValue(sp.Second.WS), s.PassP.Wc); err != nil {
		return
	}
	for k, v := range segmentCompareValue[:len(segmentCompareValue)-1] {
		switch {
		case v == 1:
			return true, err
		case v == 0 && k == len(segmentCompareValue)-2:
			return false, err
		}
	}
	return false, err
}
func (sp TaskDistribution) subIndentation(s parDef.IndexPart) (res int64, err error) {
	switch {
	case len(sp.getSecondNameStringSlice()) <= 1, len(sp.subGetLeftDirection()) <= 1, len(sp.subGetLeftDirection()) > len(sp.getSecondNameStringSlice()):
		return 2, err //退出
	case len(sp.getSecondNameStringSlice()) > 1 && len(sp.subGetLeftDirection()) <= len(sp.getSecondNameStringSlice()):
		var b bool
		if b, err = sp.boundaryIf(s); err != nil {
			return
		}
		if b {
			sp.subQueryConditionsLeftIndentation()
			return 1, err
		}
		return 2, err //跳过
	default:
		return 0, err //正常执行
	}
}
func (sp TaskDistribution) subNotSegmentationValue(s parDef.IndexPart) (int64, error) {
	pagination := sp.Second.Batch.Limit.Pagination
	switch len(sp.subGetWcValue()) {
	case 0:
		switch atomic.LoadInt64(pagination) {
		case 0:
			atomic.SwapInt32(sp.Second.Batch.Limit.ModifyS, 0)
			return sp.subIndentation(s)
		case 1:
			swapLimitPagination(pagination, 0)
		default:
			atomic.SwapInt32(sp.Second.Batch.Limit.ModifyS, 1)
			swapLimitPagination(pagination, atomic.LoadInt64(pagination)/2)
		}
		return 1, nil //跳过
	default:
		return 0, nil
	}
}
func (sp TaskDistribution) SecondColumnType() bool {
	var event = "[columnType]"
	swapAtomicValue(sp.Second.Type, func() (res []string) {
		for _, v := range sp.SrcParameter.Object.IndexCol {
			res = append(res, getIndexColTypeMap(sp.SrcParameter.Object, v).TypeBelong)
		}
		return
	}())
	swapAtomicValue(sp.Second.Null, nullMeta(func() (res []string) {
		for _, v := range sp.SrcParameter.Object.IndexCol {
			res = append(res, getIndexColTypeMap(sp.SrcParameter.Object, v).ColNullMap)
		}
		return
	}()))
	infoActive(fmt.Sprintf("(%v) %v Get the index column data type of table %v.%v. index column is {%v} column dataType is {%v}", sp.LogSeq, event, sp.TableObject.Schema, sp.TableObject.Table, sp.getSecondNameStringSlice(), getTypeValue(sp.Second.Type)))
	return true
}
func (sp *TaskDistribution) subRunInit(s parDef.IndexPart) bool {
	var (
		event                      = "[second-secondRunInit]"
		loopFrequency              int64
		wc, ws                     atomic.Value
		name, Type, null           atomic.Value
		breakMd5, swsMd5, errorStr atomic.Value
	)
	sp.SrcParameter = sp.Parameter[0]
	sp.Second.Type = &Type
	sp.Second.Null = &null
	sp.Second.Name = &name
	sp.Second.SwsMd5 = &swsMd5
	sp.Second.BreakMd5 = &breakMd5
	sp.Second.ErrorStr = &errorStr
	sp.Object.Column = sp.SrcParameter.Object.Column
	sp.Second.Name.Store(s.NewIndexCol)
	if len(sp.getSubLeftDirection(s.WhereGenerate.LeftDirection)) == 0 {
		return false
	}
	infoActive(fmt.Sprintf("(%v-%v) %v setup2&: start dispos second index segment:left:{%v} right:{%v} of table %v.%v(%v).", s.LogSeq, sp.LogSeq, event, getAtomicValue(s.WhereGenerate.LeftDirection), getAtomicValue(s.WhereGenerate.RightDirection), sp.TableObject.Schema, sp.TableObject.Table, sp.TableObject.PartitionName))
	if !sp.SecondColumnType() {
		return false
	}
	sp.Second.Batch = sp.pInputInit()
	sp.Second.WC = &wc
	sp.Second.WS = &ws
	sp.Second.LoopFrequency = &loopFrequency
	swapAtomicValue(sp.Second.Batch.WhereGenerate.LeftDirection, sp.getSubLeftDirection(s.WhereGenerate.LeftDirection))
	swapAtomicValue(sp.Second.Batch.WhereGenerate.RightDirection, sp.getSubLeftDirection(s.WhereGenerate.RightDirection))
	atomic.SwapInt32(sp.Second.Batch.WhereGenerate.NullBool, atomic.LoadInt32(s.WhereGenerate.NullBool))
	return true
}
